<template>
  <div>
    <el-row :gutter="20">
      <el-col :sm="24" :lg="24">

        <div class="chart-container">
          <!-- 曲线图容器 -->
          <div ref="lineChartEl" class="chart-item" style="width: 50%; height: 500px;"></div>
          <!-- 饼图容器 -->
          <div ref="pieChartEl" class="chart-item" style="width: 50%; height: 500px;"></div>
        </div>
      </el-col>
    </el-row>
    <el-row :gutter="20" class="flex-container">
      <div>
        <h1>成本情况表</h1>
        <table class="cost-table">
          <thead>
          <tr>
            <th rowspan="2">大类</th>
            <th v-for="year in yearsRange" :colspan="2" :key="year">{{ year }}</th>
          </tr>
          <tr>
            <template v-for="year in years" :key="year">
              <th>总成本</th>
              <th>单公里成本</th>
            </template>
          </tr>
          </thead>

          <tbody>
          <tr v-for="(item, index) in tableData" :key="index"
              :class="{ highlight: item.category === '合计' }">
            <td>{{ item.category }}</td>
            <template v-for="year in yearsRange" :key="year">
              <td>{{ format(item[year]?.total) }}</td>
              <td>{{ format(item[year]?.perKm) }}</td>
            </template>
          </tr>
          </tbody>
        </table>
        <button @click="exportToExcel">下载Excel</button>
      </div>
    </el-row >
    <el-row :gutter="10">
      <div class="year-selector" >
        <label :style="{ paddingLeft: '20px' }">选择年份：</label>
        <select v-model="selectedYear">
          <option v-for="year in yearsOfYanghu" :key="year" :value="year">{{ year }}</option>
        </select>
      </div>
      <div ref="chartContainer" style="width: 100%; height: 600px;"></div>
    </el-row>
    <el-divider />

  </div>
</template>

<script setup name="Index">
const version = ref('3.8.7')
import { ref, onMounted, onBeforeUnmount, reactive } from 'vue';
import * as echarts from 'echarts';
import { getPieData,getTotalAmountYearChange,getAuditRoutineTotalAmountYearChange,
  getAuditTechnologyTotalAmountYearChange,getAuditYanghuTotalAmountYearChange,
  categoryStatisticsMoneyTotal} from '@/api/system/visual.js';

// ------------ 数据与配置 ------------
const chartData = reactive( {
  // 年份数据（2018-2023）
  years: ['2018年', '2019年', '2020年', '2021年', '2022年', '2023年'],
  // 模拟合同金额数据（单位：万元）
  amounts: [850, 920, 880, 1120, 1350, 1500],
  // 采购方式数据
  purchaseMethods: [
    { value: 2850, name: '公开招标' },
    { value: 1620, name: '邀请招标' },
    { value: 1480, name: '竞争性谈判' },
    { value: 1320, name: '单一来源采购' },
    { value: 1280, name: '询价采购' }
  ]
});

async function fetchData() {
  try {
    const response = await getPieData();
    chartData.purchaseMethods = response.data; // 假设返回数据在 response.data 里
    pieChart.setOption({
      legend: {
        data: chartData.purchaseMethods.map(item => item.name) // 同步图例名称
      },
      series: [{
        data: chartData.purchaseMethods // 同步饼图数据
      }]
    });
    // 调用第二个接口（年度变化数据）
    const lineResponse = await getTotalAmountYearChange();
    chartData.years = lineResponse.data.map(item => `${item.year}年`);
    chartData.amounts = lineResponse.data.map(item => item.totalAmount);

    lineChart.setOption({
      xAxis: {
        data: chartData.years
      },
      series: [{
        data: chartData.amounts
      }]
    });
  } catch (err) {
    error.value = "获取数据失败：" + err.message;
  }
}

// 曲线图配置（调整为年度数据）
const lineChartOption = {
  title: {
    text: '年度合同总价款变化趋势',
    left: 'center',
    textStyle: {
      fontSize: 18,
      color: '#333'
    }
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross',
      label: {
        backgroundColor: '#6a7985'
      }
    },
    formatter: params => {
      return `${params[0].axisValue}<br/>
              <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#409EFF;"></span>
              ${params[0].seriesName}: ${params[0].value} 万元`;
    }
  },
  toolbox: {
    right: 20,
    feature: {
      saveAsImage: {
        show: true,
        title: '保存为图片',
        pixelRatio: 2
      },
      dataView: {
        show: true,
        title: '数据视图',
        readOnly: true,
        lang: ['数据视图', '关闭', '刷新']
      },
      magicType: {
        show: true,
        title: '切换类型',
        type: ['line', 'bar']
      }
    }
  },
  xAxis: {
    type: 'category',
    data: chartData.years,  // 改为使用years数据
    axisLabel: {
      // 移除旋转设置，因为年份文字较短
      margin: 15
    },
    axisTick: {
      alignWithLabel: true
    }
  },
  yAxis: {
    type: 'value',
    name: '金额（万元）',
    axisLine: {
      show: true
    },
    splitLine: {
      lineStyle: {
        type: 'dashed'
      }
    }
  },
  series: [{
    name: '合同金额',
    type: 'line',
    smooth: true,
    symbol: 'circle',
    symbolSize: 8,
    itemStyle: {
      color: '#409EFF',
      borderWidth: 2
    },
    lineStyle: {
      width: 3,
      shadowColor: 'rgba(64,158,255,0.3)',
      shadowBlur: 10,
      shadowOffsetY: 8
    },
    areaStyle: {
      color: {
        type: 'linear',
        x: 0,
        y: 0,
        x2: 0,
        y2: 1,
        colorStops: [{
          offset: 0, color: 'rgba(64,158,255,0.4)'
        }, {
          offset: 1, color: 'rgba(64,158,255,0.02)'
        }]
      }
    },
    data: chartData.amounts
  }],
  grid: {
    top: 80,
    bottom: 40,
    containLabel: true
  }
};

// 饼图配置保持不变
const pieChartOption = {
  title: {
    text: '采购方式占比',
    left: 'center',
    textStyle: {
      fontSize: 18,
      color: '#333'
    }
  },
  tooltip: {
    trigger: 'item',
    formatter: '{a} <br/>{b}: {c}万元 ({d}%)'
  },
  legend: {
    orient: 'vertical',
    right: 10,
    top: 'center',
    data: chartData.purchaseMethods.map(item => item.name)
  },
  series: [
    {
      name: '采购金额',
      type: 'pie',
      radius: ['50%', '70%'],
      avoidLabelOverlap: false,
      itemStyle: {
        borderRadius: 10,
        borderColor: '#fff',
        borderWidth: 2
      },
      label: {
        show: false,
        position: 'center'
      },
      emphasis: {
        label: {
          show: true,
          fontSize: '18',
          fontWeight: 'bold',
          formatter: '{b}\n{c}万元 ({d}%)'
        }
      },
      labelLine: {
        show: false
      },
      data: chartData.purchaseMethods
    }
  ]
};

// ------------ 图表生命周期 ------------
const lineChartEl = ref(null);
const pieChartEl = ref(null);
let lineChart = null;
let pieChart = null;

const resizeCharts = () => {
  lineChart?.resize();
  pieChart?.resize();
};

const chartContainer = ref(null);
let chart = null;
const selectedYear = ref(2023);


// 模拟数据
const data = reactive({
  2021: { 路基: 320, 路面: 480, 桥梁: 210, 隧道: 150 },
  2022: { 路基: 350, 路面: 510, 桥梁: 240, 隧道: 180 },
  2023: { 路基: 380, 路面: 550, 桥梁: 270, 隧道: 210 },
  2020: { 路基: 380, 路面: 550, 桥梁: 270, 隧道: 210 },
  2024: { 路基: 380, 路面: 550, 桥梁: 270, 隧道: 210 }
});
const yearsOfYanghu = reactive([]);
const updateYears = () => {
  yearsOfYanghu.length = 0; // 清空数组

  // 安全提取数字年份
  const years = Object.keys(data)
      .filter(key => !isNaN(Number(key))) // 过滤掉非数字键
      .map(Number) // 转换为数字
      .sort((a, b) => a - b); // 按升序排序

  yearsOfYanghu.push(...years); // 添加到响应式数组
};
console.log(yearsOfYanghu)
updateYears();
const fetchStatistics = async () => {
  try {
    const response = await categoryStatisticsMoneyTotal();
    console.log(response)
    Object.keys(data).forEach(key => delete data[key]); // 先清空
    Object.assign(data, response.data); // 再合并新数据
    updateYears();
  } catch (err) {
    error.value = `获取统计失败: ${err.message}`;
    console.error('接口错误:', err);
  }
};


const initChart = () => {
  chart = echarts.init(chartContainer.value);
  updateChart();
};


const updateChart = () => {
  const option = {
    title: {
      text: selectedYear.value+'年养护工程成本分析',
      left: 'center',
      textStyle: {
        fontSize: 20,
        color: '#333'
      }
    },
    tooltip: {
      trigger: 'axis',
      formatter: params => `
        <div style="padding: 5px 10px;">
          <div>${params[0].name}</div>
          <div style="display: flex; align-items: center;">
            <span style="display:inline-block;width:10px;height:10px;background:${params[0].color};margin-right:5px;"></span>
            ${params[0].value} 万元
          </div>
        </div>
      `
    },
    xAxis: {
      type: 'category',
      data: Object.keys(data[selectedYear.value]),
      axisLabel: {
        rotate: 30,
        margin: 15
      }
    },
    yAxis: {
      type: 'value',
      name: '成本（万元）',
      splitLine: {
        lineStyle: {
          type: 'dashed'
        }
      }
    },
    series: [{
      type: 'bar',
      data: Object.values(data[selectedYear.value]).map((value, index) => ({
        value,
        itemStyle: {
          color: ['#1890ff', '#13c2c2', '#52c41a', '#fadb14'][index % 4]
        }
      })),
      barWidth: '60%',
      label: {
        show: true,
        position: 'top',
        formatter: '{c} 万'
      }
    }]
  };

  chart.setOption(option, true);
};



onMounted(() => {
  fetchData()
  fetchAllData()
  fetchStatistics()
  if (!lineChartEl.value || !pieChartEl.value) return;

  // 初始化曲线图
  lineChart = echarts.init(lineChartEl.value);
  lineChart.setOption(lineChartOption);

  // 初始化饼图
  pieChart = echarts.init(pieChartEl.value);
  pieChart.setOption(pieChartOption);
  console.log(pieChartEl.value)

  // 响应式处理
  window.addEventListener('resize', resizeCharts);
  initChart();
  window.addEventListener('resize', () => chart?.resize());

});

onBeforeUnmount(() => {
  // 清理资源
  window.removeEventListener('resize', resizeCharts);
  lineChart?.dispose();
  pieChart?.dispose();

  window.removeEventListener('resize', () => chart?.resize());
  chart?.dispose();
});


import { utils, writeFile } from 'xlsx';

const tableData = ref([])
const yearsRange = ref([]) // 存储实际年份范围
const HIGHWAY_LENGTH = 114.97 // 公路长度常量

// 从所有数据中提取年份范围
function extractYearsRange(dataArrays) {
  const allYears = new Set()

  // 收集所有接口返回的年份
  dataArrays.forEach(dataArray => {
    dataArray.forEach(item => {
      allYears.add(item.year)
    })
  })

  // 转换为数组并排序
  const sortedYears = Array.from(allYears).sort()

  // 确定最小和最大年份
  const minYear = Math.min(...sortedYears)
  const maxYear = Math.max(...sortedYears)

  // 生成连续的年份范围
  const range = []
  for (let year = minYear; year <= maxYear; year++) {
    range.push(year)
  }

  return range
}

// 初始化表格数据结构
function initTableData(years) {
  const categories = [
    '日常维护',
    '养护工程',
    '科技创新费',
    '合计'
  ]

  return categories.map(category => {
    const row = { category }
    years.forEach(year => {
      row[year] = {
        total: null,
        perKm: null
      }
    })
    return row
  })
}

// 处理单个接口数据
function processApiData(apiData, categoryIndex, years) {
  apiData.forEach(item => {
    const year = item.year
    if (years.includes(year)) {
      const total = item.totalAmount
      const perKm = total !== null ? +(total / HIGHWAY_LENGTH).toFixed(2) : null

      tableData.value[categoryIndex][year] = { total, perKm }
    }
  })
}

// 获取所有数据
async function fetchAllData() {
  try {
    // 并行调用所有接口
    const [totalRes, routineRes, techRes, yanghuRes] = await Promise.all([
      getTotalAmountYearChange(),
      getAuditRoutineTotalAmountYearChange(),
      getAuditTechnologyTotalAmountYearChange(),
      getAuditYanghuTotalAmountYearChange()
    ])

    // 提取实际年份范围
    yearsRange.value = extractYearsRange([
      totalRes.data,
      routineRes.data,
      techRes.data,
      yanghuRes.data
    ])

    // 初始化表格结构
    tableData.value = initTableData(yearsRange.value)

    // 处理各分类数据
    processApiData(routineRes.data, 0, yearsRange.value) // 日常维护
    processApiData(yanghuRes.data, 1, yearsRange.value)  // 养护工程
    processApiData(techRes.data, 2, yearsRange.value)     // 科技创新费

    // 处理合计数据
    processApiData(totalRes.data, 3, yearsRange.value)    // 合计

    return {
      tableData: tableData.value,
      yearsRange: yearsRange.value
    }

  } catch (error) {
    console.error('获取数据失败:', error)
    throw error
  }
}


// 格式化显示（保留两位小数）
const format = (value) => {
  return value?.toFixed(2) ?? '-'
}

// 导出功能保持原样
const exportToExcel = () => {
  const ws = utils.json_to_sheet(tableData.value.map(item => {
    const row = { 大类: item.category }
    yearsRange.forEach(year => {
      row[`${year}总成本`] = item[year]?.total || 0
      row[`${year}单公里成本`] = item[year]?.perKm || 0
    })
    return row
  }))
  const wb = utils.book_new()
  utils.book_append_sheet(wb, ws, "养护成本")
  writeFile(wb, "养护成本报表.xlsx")
}


function goTarget(url) {
  window.open(url, '__blank')
}

watch(selectedYear, () => {
  updateChart()
})


</script>

<style scoped lang="scss">
.home {
  blockquote {
    padding: 10px 20px;
    margin: 0 0 20px;
    font-size: 17.5px;
    border-left: 5px solid #eee;
  }
  hr {
    margin-top: 20px;
    margin-bottom: 20px;
    border: 0;
    border-top: 1px solid #eee;
  }
  .col-item {
    margin-bottom: 20px;
  }

  ul {
    padding: 0;
    margin: 0;
  }

  font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 13px;
  color: #676a6c;
  overflow-x: hidden;

  ul {
    list-style-type: none;
  }

  h4 {
    margin-top: 0px;
  }

  h2 {
    margin-top: 10px;
    font-size: 26px;
    font-weight: 100;
  }

  p {
    margin-top: 10px;

    b {
      font-weight: 700;
    }
  }

  .update-log {
    ol {
      display: block;
      list-style-type: decimal;
      margin-block-start: 1em;
      margin-block-end: 1em;
      margin-inline-start: 0;
      margin-inline-end: 0;
      padding-inline-start: 40px;
    }
  }
}
.chart-container {
  display: flex;
  width: 100%;
}

.chart-item {
  flex: 1;
  min-width: 0;
  padding: 10px;
}

.highlight td {
  background-color: #e3f2fd !important;
}

.cost-table {
  border: 2px solid #ebeef5;  /* 修改为更柔和的边框颜色 */
  border-collapse: collapse;  /* 必须添加 */
  width: 100%;
  margin: 20px 0;
  font-size: 14px;
}

/* 表头样式 */
.cost-table th {
  background-color: #f5f7fa;  /* 更柔和的背景色 */
  color: #606266;
  font-weight: 600;
  padding: 15px 20px;
  border-bottom: 2px solid #ebeef5;  /* 底部边框 */
}

/* 数据行样式 */
.cost-table td {
  padding: 12px 20px;
  color: #606266;
  border-bottom: 1px solid #ebeef5;  /* 行间分隔线 */
}

/* 最后一行的底部边框 */
.cost-table tr:last-child td {
  border-bottom: none;
}

/* 高亮行样式 */
.highlight td {
  background-color: #f0f8ff !important;
  border-bottom: 2px solid #cce0f5;  /* 保持与高亮色系一致 */
}

/* 鼠标悬停效果 */
.cost-table tr:hover td {
  background-color: #fafafa;
}

/* 首列加粗 */
.cost-table td:first-child {
  font-weight: 500;
  color: #303133;
}

.download-btn {
  padding: 8px 16px;
  background: #409eff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.download-btn:hover {
  background: #66b1ff;
}

.chart-container {
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.1);
}

.year-selector {
  margin-bottom: 20px;
  text-align: center;
}

.el-radio-group {
  display: inline-flex;
  gap: 10px;
}
.flex-container {
  display: flex;
  justify-content: center; /* 水平居中 */
  align-items: center;     /* 垂直居中 */
  height: 55vh;           /* 需要设置容器高度 */
}
</style>

